/**
 * @file 	 VD130.h
 * @brief    VD130 型变频器驱动,当前驱动实现了多段速与通信给定的控制方式
 * @author 	 wenbo
 * @version  1.0
 * @date 	 2023-01-05
 *
 * @copyright Copyright (c) 2023  YGL
 *
 */

#ifndef __VD130_H
#define __VD130_H

#include "../../bsp/bsp.h"

 /*
  * 当前驱动支持两种控制方式：
  * [端子选择多段速]:
  *     在将变频器参数一次性配置OK后,可完全脱离通信仅通过IO进行控制(电流采集通过模拟信号)
  *     多段速最多可以设置 16 种状态,去除全高/低为 0 速状态，剩下 14 种状态,正反方向各占一半就是 7 组速度
  *     此种方式控制涉及到以下接口:
  *     xp_vd130_init(...) 初始化驱动 handle (必须, 其它接口依赖其返回的 handle, 不建议注册事件回调)
  *     xp_vd130_run_stageSpeed(...) 控制 IO 输出对应的段速(必须, 应用层建议封装成 speed_level 接口)
  *     xp_vd130_stageSpeed_config(...) 应用层动态配置段速列表(非必须,一般应用场景下速度 level 相对固定)
  *     xp_vd130_get_current(...) 通信方式读取电流值(非必须, 如果需要通信方式采集电流,建议注册回调,由驱动层线程轮询)
  * [通信给定方式]:
  *     此模式下不需要 IO 连接,所有操作皆通过通信方式,安全性由配置的通信超时停机功能保障
  *     此种方式控制涉及到以下接口:
  *     xp_vd130_init(...) 初始化驱动 handle (必须, 其它接口依赖其返回的 handle, 建议注册事件回调)
  *     xp_vd130_run_comm(...) 设置目标运行频率到变频器
  * [注意]:
  * xp_vd130_init(...) 接口仅初始化驱动结构,不实际与变频器通信
  * 以上两种方式控制皆需要保证变频器已经出厂配置过,可通过调用 xp_vd130_global_config(...) 接口对目标变频器进行初始化配置相关参数
  * (需要人工操作面板配置好通信相关参数,例如波特率,校验位,从机ID)
  * 调用 xp_vd130_global_config(...) 接口前需要初始化以下参数(init 时会分配默认参数,仅需配置更新部分)
  *  .mode               // 控制模式
  *  .isReverseDir       // 是否翻转方向
  *  .commOvertime_ms    // 通信超时时间(ms)
  *  .maxFreq            // 最大频率(50.00～630.00Hz)
  *  .acceleration       // 加速度 Hz/s
  *  .deceleration       // 减速度 Hz/s
  *  .motorRatedFreq     // 电机额定频率(Hz)(铭牌)
  *  .motorRatedCurr     // 电机额定电流(A)(铭牌)
  *  .motorRatedVol      // 电机额定电压(V)(铭牌)
  *  .motorRatedPower    // 电机额定功率(W)(铭牌)
  *  .motorRatedSpeed    // 电机额定转速(rpm)(铭牌)
  *  .stageSpeedList[16] // 多段速列表(-100.0%～100.0%)
  *  .gpio_DI1           // DI1 GPIO(未使用则不配置)
  *  .gpio_DI2           // DI2 GPIO(未使用则不配置)
  *  .gpio_DI3           // DI3 GPIO(未使用则不配置)
  *  .gpio_DI4           // DI4 GPIO(未使用则不配置)
  *  .gpio_DI5           // DI5 GPIO(未使用则不配置)
  * 各 DI 端子功能在 xp_vd130_global_config 中已经默认配置,如需动态配置,调用 xp_vd130_DI_func_config(...) 接口
 */


typedef enum {
    VD130_EVENT_CURRENT = 0,    // 电流读取事件
    VD130_EVENT_CONNECT,        // 连接事件
    VD130_EVENT_FAULT,          // 故障代码读取事件
} VD130_EVENT_enmu;

typedef enum {
    VD130_MODE_NOINIT = 0,      // 未初始化状态
    VD130_MODE_PORT,            // 端子运行方式,多段速
    VD130_MODE_COMM,            // 通信给定频率方式
} VD130_MODE_enmu;

typedef struct VD130_CTX_st VD130_CTX;
typedef void (*vd130_event_callback)(VD130_CTX* ctx, VD130_EVENT_enmu eventId, uint32_t data);

struct VD130_CTX_st
{
    /*********内部变量,勿操作*********/
    bool isOnline;
    bool isReadCurrent;

    uint8_t slaveId;
    uint8_t port;
    uint8_t lostCnts;

    vd130_event_callback event_cb;
    uint32_t interval_ms;

    int32_t lastPos;
    aos_mutex_t* mutex;

    int16_t         current;            // 变频器当前输出电流
    /********************************/

    /***********************初始化配置项******************************/
    VD130_MODE_enmu mode;               // 控制模式
    bool            isReverseDir;       // 是否翻转方向
    int16_t         commOvertime_ms;    // 通信超时时间(ms)
    uint8_t         maxFreq;            // 最大频率(50.00～630.00Hz)
    uint8_t         acceleration;       // 加速度 Hz/s
    uint8_t         deceleration;       // 减速度 Hz/s

    float           motorRatedFreq;     // 电机额定频率(Hz)(铭牌)
    float           motorRatedCurr;     // 电机额定电流(A)(铭牌)
    float           motorRatedVol;      // 电机额定电压(V)(铭牌)
    float           motorRatedPower;    // 电机额定功率(W)(铭牌)
    float           motorRatedSpeed;    // 电机额定转速(rpm)(铭牌)

    int16_t         stageSpeedList[16]; // 多段速列表(-100.0%～100.0%)

    struct {
        uint8_t func;
        Type_GPIO_Def io;
    } DIx[5];
    /****************************************************************/
};


/********段速配置建议表*****
DI4 DI3 DI2 DI1  ID  FREQ
 0 | 0 | 0 | 0 | 0 | 0
 0 | 0 | 0 | 1 | 1 | 10
 0 | 0 | 1 | 0 | 2 | -10
 0 | 0 | 1 | 1 | 3 | 30
 0 | 1 | 0 | 0 | 4 | -30
 0 | 1 | 0 | 1 | 5 | 50
 0 | 1 | 1 | 0 | 6 | -50
 0 | 1 | 1 | 1 | 7 | 0
 1 | 0 | 0 | 0 | 8 | 0
 1 | 0 | 0 | 1 | 9 | 0
 1 | 0 | 1 | 0 | A | 0
 1 | 0 | 1 | 1 | B | 0
 1 | 1 | 0 | 0 | C | 0
 1 | 1 | 0 | 1 | D | 0
 1 | 1 | 1 | 0 | E | 0
 1 | 1 | 1 | 1 | F | 0
**************************/

/* 默认参数 */
#define VD130_DEFAULT_PARAMS()  \
    (VD130_CTX) {               \
        .mode = VD130_MODE_PORT,\
        .maxFreq = 50,          \
        .acceleration = 25,     \
        .deceleration = 25,     \
        .commOvertime_ms = 3000,\
        .motorRatedFreq = 50,   \
        .motorRatedCurr = 1.2,  \
        .motorRatedVol = 220,   \
        .motorRatedPower = 400, \
        .stageSpeedList = {     \
            0,                  \
            10, -10,            \
            30, -30,            \
            50, -50,            \
            0, -0,              \
            0, -0,              \
            0, -0,              \
            0, -0,              \
            0                   \
        },                      \
        .DIx[0] = {             \
            .func = 13,         \
            .io.boardId = -1,   \
        },                      \
        .DIx[1] = {             \
            .func = 14,         \
            .io.boardId = -1,   \
        },                      \
        .DIx[2] = {             \
            .func = 15,         \
            .io.boardId = -1,   \
        },                      \
        .DIx[3] = {             \
            .func = 10,         \
            .io.boardId = -1,   \
        },                      \
        .DIx[4] = {             \
            .func = 0,          \
            .io.boardId = -1,   \
        },                      \
    }

/***********************************API*************************************/
/**
 * @brief       初始化 VD130 变频器驱动
 * @param[in]	slaveId             从机ID (1~255)
 * @param[in]	port                modbus 端口 (1,2)
 * @param[in]	baudrate            波特率
 * @param[in]	parity              校验位 (0: MB_PAR_NONE,1: MB_PAR_ODD,2: MB_PAR_EVEN)
 * @param[in]	event_cb            结果变化回调 (非空则创建线程轮询结果寄存器)
 * @return      VD130_CTX*          返回接口handle
 */
VD130_CTX* const xp_vd130_init(uint8_t slaveId, uint8_t port, uint32_t baudrate, uint8_t parity, vd130_event_callback event_cb);
/**
 * @brief       去初始化 VD130 变频器驱动
 * @param[in]	ctx             接口handle
 * @return      bool            执行结果
 */
bool xp_vd130_deinit(VD130_CTX* ctx);
/**
 * @brief       设置启/停电流值轮询
 * @param[in]	ctx                 接口handle
 * @param[in]	isReadCurrent       是否启动轮询电流值
 * @return      bool                true: 配置成功
 */
bool xp_vd130_set_loop_state(VD130_CTX* const ctx, bool isReadCurrent);
/**
 * @brief       配置轮询线程的轮询间隔
 * @param[in]	ctx                 接口handle
 * @param[in]	ms                  间隔时间
 */
void xp_vd130_set_thread_loop_interval_ms(VD130_CTX* const ctx, uint32_t ms);
/**
 * @brief       获取变频器在线状态(由历史通信结果判断)
 * @param[in]	ctx                 接口handle
 * @return      bool                执行结果
 */
bool xp_vd130_is_online(VD130_CTX* const ctx);
/**
 * @brief       通过 handle 获取 slaveId
 * @param[in]	ctx                 接口handle
 * @return      uint8_t             slaveId
 */
uint8_t xp_vd130_get_id(VD130_CTX* const ctx);
/**
 * @brief       VD130 变频器段速自定义(非必须调用)
 * @param[in]	ctx                 接口handle
 * @param[in]	stageSpeedList      段速数组(0.1Hz ? xx% ? 文档描述不清晰)
 * @param[in]	listLen             数组长度(1~16)
 * @return      bool                true: 配置成功
 */
bool xp_vd130_stageSpeed_config(VD130_CTX* const ctx, int16_t stageSpeedList[], uint8_t listLen);
/**
 * @brief       VD130 变频器DI功能自定义(非必须调用)
 * @param[in]	ctx                 接口handle
 * @param[in]	DI_func             DI 功能数组
 * @param[in]	listLen             数组长度(1~5)
 * @return      bool                true: 配置成功
 */
bool xp_vd130_DI_func_config(VD130_CTX* const ctx, int16_t DI_func[], uint8_t listLen);
/**
 * @brief       VD130 变频器运行通过段速模式(段速需已提前配置)
 * @param[in]	ctx                 接口handle
 * @param[in]	stageIndex          段速 ID (0~15)
 * @return      bool                true: 运行成功
 */
bool xp_vd130_run_stageSpeed(VD130_CTX* const ctx, uint8_t stageIndex);
/**
 * @brief       VD130 变频器获取输出电流
 * @param[in]	ctx                 接口handle
 * @param[in]	pResult             结果数据指针(可为NULL)
 * @return      bool                true: 获取成功
 */
bool xp_vd130_get_current(VD130_CTX* const ctx, uint16_t* pResult);
/**
 * @brief       VD130 变频器获取故障码
 * @param[in]	ctx                 接口handle
 * @param[in]	pResult             结果数据指针(可为NULL)
 * @return      bool                true: 获取成功
 */
bool xp_vd130_get_fault_code(VD130_CTX* const ctx, uint16_t* pResult);
/**
 * @brief       VD130 变频器清除故障
 * @param[in]	ctx                 接口handle
 * @return      bool                true: 清除成功
 */
bool xp_vd130_clear_fault(VD130_CTX* const ctx);
/**
 * @brief       VD130 变频器运行通过通信模式
 * @param[in]	ctx                 接口handle
 * @param[in]	freq                目标频率 (Hz)
 * @return      bool                true: 运行成功
 */
bool xp_vd130_run_comm(VD130_CTX* const ctx, float freq);
/**
 * @brief       VD130 变频器全局初始化,参数掉电保存,因此仅在出厂时调用
 * @param[in]	ctx                 接口handle
 * @return      bool                true: 配置成功
 */
bool xp_vd130_global_config(VD130_CTX* const ctx);


/* 故障代码对照表 */
/*********************
    0=无故障
    1=加速过流
    2=减速过流
    3=稳速过流
    4=停机过流
    5=加速软件过流
    6=减速软件过流
    7=稳速软件过流
    8=停机软件过流
    9=加速过压
    10=减速过压
    11=稳速过压
    12=停机过压
    13=加速欠压
    14=减速欠压
    15=稳速欠压
    16=停机欠压
    17=EPROM
    18=散热器过热
    19=过载
    20=保留
    21=外部故障
    22=通信超时故障
    23=加速软件过压
    24=减速软件过压
    25=稳速软件过压
    26=停机软件过压
    27=停车掉电
    28=运行掉电
    29=停车缺相
    30=运行缺相
    31=加速VCE过流故障
    32=加速速VCE过流故障
    33=稳速VCE过流故障
    34=停车VCE过流故障
*/
#endif